<?php

/**
 * HighchartsWidget class file.
 *
 * @author fred 
 * @version 3.0
 * 
 * based on initial work of Milo Shuman * 
 * @author Milo Schuman <miloschuman@gmail.com>
 * @link https://github.com/miloschuman/yii-highcharts/
 * @license http://www.opensource.org/licenses/mit-license.php MIT License
 * @version 2.3.5
 */

/**
 * HighchartsWidget encapsulates the {@link http://www.highcharts.com/ Highcharts}
 * charting library's Chart object.
 *
 * To use this widget, you may insert the following code in a view:
 * <pre>
 * $this->Widget('ext.highcharts.HighchartsWidget', array(
 *    'options'=>array(
 *       'title' => array('text' => 'Fruit Consumption'),
 *       'xAxis' => array(
 *          'categories' => array('Apples', 'Bananas', 'Oranges')
 *       ),
 *       'yAxis' => array(
 *          'title' => array('text' => 'Fruit eaten')
 *       ),
 *       'series' => array(
 *          array('name' => 'Jane', 'data' => array(1, 0, 4)),
 *          array('name' => 'John', 'data' => array(5, 7, 3))
 *       )
 *    )
 * ));
 * </pre>
 *
 * By configuring the {@link $options} property, you may specify the options
 * that need to be passed to the Highcharts JavaScript object. Please refer to
 * the demo gallery and documentation on the {@link http://www.highcharts.com/
 * Highcharts website} for possible options.
 *
 * Alternatively, you can use a valid JSON string in place of an associative
 * array to specify options:
 *
 * <pre>
 * $this->Widget('ext.highcharts.HighchartsWidget', array(
 *    'options'=>'{
 *       "title": { "text": "Fruit Consumption" },
 *       "xAxis": {
 *          "categories": ["Apples", "Bananas", "Oranges"]
 *       },
 *       "yAxis": {
 *          "title": { "text": "Fruit eaten" }
 *       },
 *       "series": [
 *          { "name": "Jane", "data": [1, 0, 4] },
 *          { "name": "John", "data": [5, 7,3] }
 *       ]
 *    }'
 * ));
 * </pre>
 *
 * Note: You must provide a valid JSON string (e.g. double quotes) when using
 * the second option. You can quickly validate your JSON string online using
 * {@link http://jsonlint.com/ JSONLint}.
 *
 * Note: You do not need to specify the <code>chart->renderTo</code> option as
 * is shown in many of the examples on the Highcharts website. This value is
 * automatically populated with the id of the widget's container element. If you
 * wish to use a different container, feel free to specify a custom value.
 */
class HighchartsWidget extends CWidget {

    public $options = null;
    public $htmlOptions = null;
    private $theme = 'gray';
    private $baseUrl;

    /**
     * Renders the widget.
     */
    public function run() {
	  $this->baseUrl = Yii::app()->request->baseUrl . '/js/libs/highcharts';

	  if (is_array($this->options)) {
		$id = $this->getId();
		$this->htmlOptions['id'] = $id;
		$this->htmlOptions['class'] = 'graph';

		echo CHtml::openTag('div', $this->htmlOptions);
		echo CHtml::closeTag('div');

		// check if options parameter is a json string
		if (is_string($this->options)) {
		    if (!$this->options = CJSON::decode($this->options))
			  throw new CException('The options parameter is not valid JSON.');
		}

		// merge options with default values
		$defaultOptions = array('chart' => array('renderTo' => $id), 'exporting' => array('disabled' => true));
		$this->options = CMap::mergeArray($defaultOptions, $this->options);
		$jsOptions = CJavaScript::encode($this->options);
		$this->registerScripts($id, $jsOptions);
	  }
    }

    /**
     * Publishes and registers the necessary script files.
     *
     * @param string the id of the script to be inserted into the page
     * @param string the embedded script to be inserted into the page
     */
    protected function registerScripts($id, $jsOptions) {

	  Yii::app()->domoHelper->loadJquery();

	  $cs = Yii::app()->clientScript;
	  $cs->registerScriptFile($this->getScriptUrl('highcharts.js'));

	  // register exporting module if enabled via the 'exporting' option
	  if (isset($this->options['exporting']['enabled']) && $this->options['exporting']['enabled'] === true) {
		$cs->registerScriptFile($this->getScriptUrl('modules/exporting.js'));
	  }
	  
	  // register supplemental chart types library if needed
	  $jsMoreChart = false;
	  $moreCharts = array('gauge', 'arearange', 'areasplinerange', 'columnrange');

	  foreach ($moreCharts as $moreChart) {
		if (strpos($jsOptions, $moreChart) !== false) {
		    $jsMoreChart = true;
		    break;
		}
	  }
	  if ($jsMoreChart) {
		$cs->registerScriptFile($this->getScriptUrl('highcharts-more.js'));
	  }


	  $cs->registerScript(__CLASS__ . '#' . $id, "var chart" . $id . " = new Highcharts.Chart($jsOptions);", CClientScript::POS_LOAD);
    }

    /*
     * Manually load the theme after all graphs have been rendered
     * (must be loaded after highcharts-more.js, for example)
     */

    public function loadTheme() {
	  Yii::app()->clientScript->registerScriptFile($this->getScriptUrl('themes/' . $this->theme . '.js'));
    }

    /*
     * Get scripts url according to external or internal use of the application
     * @return string script url
     */

    protected function getScriptUrl($scriptFile) {
	  return Yii::app()->domoHelper->isExterne() ? 'http://code.highcharts.com/3.0/' . $scriptFile : $this->baseUrl . '/' . $scriptFile;
    }

}